package com.apps.java.javanote02;

import java.util.*;

public class _22集合_Set {
    /**
     * Set
     * 	一、Set集合特点
     * 		1.不包含重复的元素的集合
     * 		2.没有带索引的方法，所以不能使用普通for循环遍历
     *
     * 	二、哈希值
     * 		1.概述：哈希值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
     * 		2.如何得到哈希值：Object类中有一个方法可以获取的对象的哈希值
     * 				   public int hashCode() 返回该对象的哈希码值。
     * 		3.对象的哈希值特点
     * 			（1）同一个对象多次调用hashCode()方法返回的哈希值是相同的
     * 			（2）默认情况下，不同对象的哈希值是不同的，而重写hashCode()方法，可以实现让不同对象的哈希值相同
     *
     * 	三、HashSet集合概述和特点
     * 		特点：
     * 			1.底层数据结构是哈希表
     * 			2.对集合的迭代顺序不作任何保证，不保证存储和取出的元素顺序一致
     * 			3.没有带索引的方法，所以不能使用普通for循环遍历(可以使用迭代器和增强for循环)
     * 			4.由于是Set集合，所以是不包含重复元素的集合
     *
     * 		HashSet集合添加一个元素的过程[集合保证元素唯一性]：
     * 			1.调用对象的hashCode()方法获取对象的哈希值
     * 			2.根据对象的哈希值计算对象的存储位置
     * 			3.判断该位置是否有元素存在：
     * 				（1）没有：将元素存储到该位置
     * 				（2）有：遍历该位置的所有元素，和新存入的元素比较哈希值是否相同：
     * 					（1）都不相同：将元素存储到该位置
     * 					（2）有相同的：调用equals()方法比较对象内容是否相等：
     * 						（1）false：将元素存储到该位置
     * 						（2）true：说明元素重复，不存储该元素
     * 			HashSet集合存储元素：
     * 				要保证元素唯一性，需要重写hashCode()和equals()
     *
     * 	四、常见数据结构哈希表
     * 		哈希表：JDK8之前，底层采用数组+链表实现，可以说是一个元素为链表的数组，JDK8后，在长度比较长的时候，底层实现了优化
     *
     *
     * 	五、LinkedHashSet集合概述和特点
     * 		集合特点：
     * 			1.哈希表和链表实现的Set接口，具有可预测的迭代次序
     * 			2.由链表保证元素有序，也就是说元素的存储和取出顺序是一致的
     * 			3.由哈希表保证元素唯一，也就是说没有重复的元素
     *
     * 	六、TreeSet集合概述和特点
     * 		集合特点：
     * 			1.元素有序，这里的顺序不是指存储和取出的顺序，而是按照一定的规则进行排序，具体拍讯方式取决于构造方法。
     * 				TreeSet()：根据其元素的自然排序进行排序
     * 				TreeSet(Comparator comparator)：根据指定的比较器进行排序
     * 			2.没有带索引的方法，所以不能使用普通for循环遍历
     * 			3.由于是Set集合，所以不包含重复元素
     *
     * 		自然排序结论：
     * 			1.用TreeSet集合存储自定义对象，无参构造方法使用的是自然排序对元素进行排序的。
     * 			2.自然排序就是让元素所属的类实现Comparable接口，重写compareTo(T o)方法。
     * 			3.重写方法时，一定要注意排序规则必须按照要求的主要条件和次要条件来写
     * 		比较器排序结论：
     * 			1.用TreeSet集合存储自定义对象，带参构造方法使用的是比较器排序对元素进行排序的
     * 			2.比较器排序，就是让集合构造方法接收Comparator的实现类对象，重写Compare(T o1,T o2)方法
     * 			3.重写方法时，一定要注意排序规则必须按照要求的主要条件和次要条件来写
     *
     *
     */

    public static void main(String[] args) {
        //创建Set集合对象
        Set<String> s = new HashSet<String>();

        s.add("老王");
        s.add("老王");//不可存储重复的元素
        s.add("小明");
        s.add("小红");
        s.add("小王");

        System.out.println(s);

        //遍历
        System.out.print("循环遍历集合：");
        for(String str : s){
            System.out.print(str);//HashSet对集合的迭代顺序不作任何保证
        }

        System.out.println();

        //获取哈希值
        int hash = s.hashCode();
        System.out.println("获取哈希值：" + hash);

        //HashSet集合遍历
        //获取HashSet对象
        HashSet<String> h = new HashSet<String>();

        //添加元素
        h.add("百里红妆");
        h.add("帝北宸");
        h.add("凤舞");
        h.add("神医凰后");

        //使用迭代器遍历集合
        //获取迭代器对象
        Iterator<String> its = h.iterator();

        System.out.print("迭代器遍历hashSet集合：");
        while(its.hasNext()){
            String s1 = its.next();
            System.out.print(s1);
        }

        System.out.println();


        //使用foreach循环
        System.out.print("增强for循环遍历hashSet集合：");
        for(String ss : h){
            System.out.print(ss);
        }

        System.out.println();


        //LinkedHashSet存储字符串并遍历
        //获取集合对象
        LinkedHashSet<String> lha = new LinkedHashSet<String>();

        //添加元素
        lha.add("链1");
        lha.add("链2");
        lha.add("链3");
        lha.add("链3");

        //使用迭代器遍历
        //获取迭代器对象
        Iterator<String> it = lha.iterator();
        System.out.print("迭代器遍历LinkedHashSet集合：");
        while(it.hasNext()){
            String lhas = it.next();
            System.out.print(lhas);
        }

        System.out.println();

        //使用增强for循环遍历
        System.out.print("增强for循环遍历LinkedHashSet集合：");
        for(String lhas : lha){
            System.out.print(lhas);
        }

        System.out.println();

        //TreeSet集合遍历字符串
        //创建集合对象
        TreeSet<String> tre = new TreeSet<String>();

        //添加元素
        tre.add("Tree1");
        tre.add("Tree2");
        tre.add("Tree3");
        tre.add("Tree3");

        //循环遍历
        System.out.print("TreeSet集合遍历字符串：");
        for(String tres : tre){
            System.out.print(tres);
        }

        System.out.println();

        //创建集合对象
        TreeSet<Integer> trei = new TreeSet<Integer>();

        //添加元素
        trei.add(68);
        trei.add(25);
        trei.add(45);
        trei.add(68);

        //循环遍历
        System.out.print("TreeSet集合遍历整数：");
        for(Integer treis : trei){
            System.out.print(treis);
        }


    }
}
